package com.yict.common.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yict.common.dao.IBaseDao;
import com.yict.common.entity.PageEntity;

@Service("baseService")
public class BaseServiceImpl<T, PK extends Serializable, D extends IBaseDao<T, PK>> {
	private static Log logger = LogFactory.getLog(BaseServiceImpl.class);

	// @Resource(name="baseDao")
	private D baseDao;

	@Transactional(readOnly = false)
	public boolean save(T t) throws Exception {
		return baseDao.save(t);
	}

	@Transactional(readOnly = false)
	public boolean update(T t) throws Exception {
		return baseDao.update(t);
	}

	@Transactional(readOnly = false)
	public boolean remove(T t) throws Exception {
		return baseDao.remove(t);
	}
	
	@Transactional(readOnly = false)
	public boolean remove(PK id) throws Exception {
		return baseDao.remove(this.findById(id));
	}

	@Transactional(readOnly = false)
	public boolean remove(PK[] ids) throws Exception {
		return baseDao.remove(ids);
	}

	public T findById(PK id) {
		T vo = null;
		try {
			vo = baseDao.findbyId(id);
		} catch (Exception e) {
			logger.warn(e);
		}
		return vo;
	}

	public List<T> list(Map<String, Object> queryMap, PageEntity page,
			LinkedHashMap<String, Boolean> orderList) {
		List<T> list = new ArrayList<T>();
		int count = baseDao.queryCount(queryMap);
		if (count > 0) {
			int startIndex = 0;
			int maxSize = 0;
			if (page != null) {
				startIndex = (page.getToPage() - 1) * page.getPageSize();
				maxSize = page.getPageSize();
			}
			list = baseDao.list(queryMap, orderList, startIndex, maxSize);
		}
		if (page != null)
			page.setTotalRecord(count);
		return list;
	}
	
	/**
	 * 根据单个属性查找
	 * @param value
	 * @param propertyName
	 * @return
	 */
	public List<T> listByProperty(Object value,String propertyName){
		List<T> list = new ArrayList<T>();
		Map<String,Object> map = new HashMap<String, Object>();
		map.put(propertyName, value);
		try {
			list = baseDao.list(map, null, 0, 0);
		} catch (Exception e) {
			logger.info(e);
		}
		return list;
	}
	
	/**
	 * 根据属性查找唯一记录
	 * @param value
	 * @param propertyName
	 * @return
	 * @throws Exception
	 */
	public T findByUnique(Object value,String propertyName) {
		T vo = null;
		Map<String,Object> map = new HashMap<String, Object>();
		map.put(propertyName, value);
		List<T> list = baseDao.list(map, null, 0, 0);
		if(list.size() > 1) 
			throw new RuntimeException("与期望的唯一记录不一致，找到多个记录:" + propertyName + "=" + value);
		if(list.size() == 1) vo = list.get(0);
		return vo;
	}

	public D getBaseDao() {
		return baseDao;
	}

	public void setBaseDao(D baseDao) {
		this.baseDao = baseDao;
	}
}
